(load "@java/init")

(symbols "java+" 'pico)

(local *Exceptions)

(setq *Exceptions
  '("IllegalAccessException"
    "IllegalArgumentException"
    "ClassCastException"
    "NoSuchMethodException") )

(de pico~java+ (Object Message . @)
  (thread *Exceptions
    (catch+ 
      (thread java
        (pass Object Message)
        cons) )
    car
    (or
      (let Methods (thread Object
                     (java "getClass")
                     (javaMethods Message) )
        (thread
          (quote (Method)
            (java Method "setAccessible" T)
            (or
              (catch+ *Exceptions
                (thread Method
                  (java "invoke" Object
                    (or (rest) (array) ) )
                  cons) )
              (when (>= (javaVersion T) (1 7) )
                (catch+ *Exceptions
                  (thread Method
                    (java "invoke" Object
                      (listAsArray (rest) ) )
                    cons) ) ) ) )
          (pick Methods)
          car) )
      (quit "Method cannot be invoked on this object"
        (list Message Object (rest) ) ) ) ) )